package study.javase.io;

/**
 *  装饰模式模拟咖啡加糖加牛奶
 *  1.抽象组件：需要装饰的抽象对象（接口或抽象父类）
 *  2.具体组件：需要装饰的对象
 *  3.抽象装饰类：包含了抽象组件的引用以及装饰着共有的方法
 *  4.具体装饰类：被装饰的对象
 * @author LiShaowen
 * @date 2020/9/9 15:36
 */
public class DecorateTest1 {
    public static void main(String[] args) {
        Drink coffee = new Coffee();
        Drink sugar = new Sugar(coffee);
        Drink milk = new Milk(sugar);
        System.out.println(sugar.info()+sugar.fees());
        System.out.println(milk.info()+milk.fees());
    }
}
// 1.抽象组件：需要装饰的抽象对象（接口或抽象父类）

interface Drink{
    double fees(); // 费用
    String info(); // 说明
}
// 2.具体组件：需要装饰的对象
class Coffee implements Drink{
    private String name = "原味咖啡";
    @Override
    public double fees() {
        return 10;
    }

    @Override
    public String info() {
        return name;
    }
}

// 3.抽象装饰类：包含了抽象组件的引用以及装饰着共有的
abstract class Decorate implements Drink{
    private Drink drink;
    public Decorate(Drink drink){
        this.drink = drink;
    }

    @Override
    public double fees() {
        return this.drink.fees();
    }

    @Override
    public String info() {
        return this.drink.info();
    }

}
// 4.具体装饰类：被装饰的对象
class Milk extends Decorate{
    public Milk(Drink drink) {
        super(drink);
    }

    @Override
    public double fees() {
        return super.fees()+5;
    }

    @Override
    public String info() {
        return super.info()+"加入了牛奶";
    }
}
class Sugar extends Decorate{
    public Sugar(Drink drink) {
        super(drink);
    }

    @Override
    public double fees() {
        return super.fees()+3;
    }

    @Override
    public String info() {
        return super.info()+"加入了糖";
    }
}
